Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI Implementation with Click #2107

Merged
merged 30 commits into from
Dec 6, 2024
Merged

CLI Implementation with Click #2107

merged 30 commits into from
Dec 6, 2024

Conversation

djsaunde
Copy link
Contributor

@djsaunde djsaunde commented Nov 27, 2024

Description

This PR implements a simple CLI using click. Note the following entrypoint:

    entry_points={
        "console_scripts": [
            "axolotl=axolotl.cli.main:main",
        ],
    },

This means, once pip installed, axolotl's CLI can be used as:

axolotl [command] [args]

It support the following commands:

  • axolotl preprocess
  • axolotl train
  • axolotl inference
  • axolotl shard
  • axolotl merge_sharded_fsdp_weights
  • axolotl merge_lora
  • axolotl fetch

The last command is new functionality which allows the user to download (really, sync) the contents of the examples/ and deepspeed_configs/ directories at the top level of the axolotl project. For example:

axolotl fetch examples
axolotl fetch deepspeed_configs

An optional argument --dest [directory] allows the user to specify an output location; otherwise, this defaults to examples/ and deepspeed_configs/ in the local directory.

Motivation and Context

This change was requested in this Notion ticket. This allows axolotl users that have installed the package via pip to use the existing CLI commands, and source users to use them with a slightly simpler interface axolotl [command] ....

How has this been tested?

Ad hoc testing on axolotlai/axolotl-cloud:main-latest image on a Runpod A40 instance on this feature branch. I sparsely tested the preprocess, train, and fetch commands.

# pre install
$ axolotl train examples/openllama-3b/lora.yml 
-bash: axolotl: command not found

$ pip install -e .
...

# works
$ axolotl preprocess examples/openllama-3b/lora.yml 

# works
$ axolotl train examples/openllama-3b/lora.yml 
...

# config file overrides? works with replacing "_" with "-" (click limitation)
$ axolotl train examples/openllama-3b/lora.yml --max-steps 1 --micro-batch-size 1 --val-set-size 0

# etc.

TODO:

  • Add pytest coverage for the CLI (?)
  • Test via PyPI package installation (?)

Types of changes

This PR adds a new file src/axolotl/cli/main.py which implements the Click CLI commands, and minor changes elsewhere to accommodate them.

@djsaunde djsaunde added the enhancement New feature or request label Nov 27, 2024
@djsaunde djsaunde self-assigned this Nov 27, 2024
src/axolotl/cli/main.py Outdated Show resolved Hide resolved
@djsaunde
Copy link
Contributor Author

djsaunde commented Dec 2, 2024

Question for the team: does it make sense to write tests against this code path? I noticed there weren't tests against the existing axolotl.cli module, but I can pad these out if desired. In the interest of moving fast, we can also backlog this.

@winglian
Copy link
Collaborator

winglian commented Dec 3, 2024

Question for the team: does it make sense to write tests against this code path? I noticed there weren't tests against the existing axolotl.cli module, but I can pad these out if desired. In the interest of moving fast, we can also backlog this.

yeah, let's go ahead and take the time now to add some tests against the cli.

@djsaunde djsaunde marked this pull request as draft December 3, 2024 17:37
README.md Outdated Show resolved Hide resolved
src/axolotl/cli/main.py Outdated Show resolved Hide resolved
@winglian
Copy link
Collaborator

winglian commented Dec 4, 2024

I think the test errors:

    def test_inference_all_options(
        cli_runner, default_config, mock_inference_deps
    ):  # pylint: disable=redefined-outer-name
        """Test inference with all possible options"""
        mock_cfg = MagicMock()
        mock_inference_deps["load_cfg"].return_value = mock_cfg
    
        cli_runner.invoke(
            cli,
            [
                "inference",
                str(default_config),
                "--load-in-8bit",
                "--base-model",
                "base/model/path",
                "--lora-model-dir",
                "lora/path",
                "--prompter",
                "my_prompter",
            ],
        )
    
        # Check all options were passed through
>       cli_args = mock_inference_deps["do_inference"].call_args[1]["cli_args"]
E       TypeError: 'NoneType' object is not subscriptable

is because some of the commands run accelerate as a new subprocess, so don't directly call the do_inference function in this scope.

@djsaunde djsaunde marked this pull request as ready for review December 4, 2024 20:23
@djsaunde
Copy link
Contributor Author

djsaunde commented Dec 4, 2024

Assuming tests pass here (they're passing in Runpod at least), this PR is ready for re-review. I think I got the testing mostly right; I'm testing mostly shallowly where I assert that args that are expected are in fact passed to the relevant train / do_inference / do_clil etc. methods in similarly named axolotl.cli.preprocess / axolotl.cli.train etc. modules. A small subset of tests are more end-to-end and should be useful for preventing unexpected bugs from making it to main.

As an aside, once we deprecate the old way of running axolotl commands on the command line (e.g., accelerate launch axolotl.cli.train ...), we can probably refactor out a good bit of cruft.

@djsaunde djsaunde requested a review from winglian December 5, 2024 05:13
@djsaunde
Copy link
Contributor Author

djsaunde commented Dec 5, 2024

Adding context from Slack:

I think something weird is going on with the logging. I couldn't debug it after a few hours of trying so I've moved the tests to tests/e2e/patched for now. I think maybe the test_validations.py could be moved there instead as I think that's what's causing the issue with the caplog logic, but I'm not sure.

I also simplified some of the CLI tests so they're no longer running simple preprocess / train / shard etc. commands end to end for the sake of runtime. We have other test coverage that actually tests this functionality, so I think there's no need to duplicate.

README.md Outdated Show resolved Hide resolved
outputs Show resolved Hide resolved
src/axolotl/cli/utils.py Show resolved Hide resolved
src/axolotl/cli/utils.py Show resolved Hide resolved
src/axolotl/cli/utils.py Outdated Show resolved Hide resolved
tests/e2e/patched/cli/conftest.py Outdated Show resolved Hide resolved
src/axolotl/cli/main.py Show resolved Hide resolved
outputs Show resolved Hide resolved
src/axolotl/cli/train.py Outdated Show resolved Hide resolved
@djsaunde
Copy link
Contributor Author

djsaunde commented Dec 5, 2024

I need to add a way to pass accelerate launch args as well.

@winglian
Copy link
Collaborator

winglian commented Dec 5, 2024

need to update pytest calls in https://github.com/axolotl-ai-cloud/axolotl/blob/main/.github/workflows/tests.yml#L82 and on line 126 as well (and probably the nightly tests too)

@djsaunde djsaunde merged commit fc973f4 into main Dec 6, 2024
10 checks passed
djsaunde added a commit that referenced this pull request Dec 16, 2024
* Initial CLI implementation with click package

* Adding fetch command for pulling examples and deepspeed configs

* Automating default options for CliArgs classes

* Mimicking existing no config behavior

* bugfix in choose_config

* Updating fetch to sync instead of re-download

* bugfix

* isort fix

* fixing yaml isort order

* pre-commit fixes

* simplifying argument parsing -- pass through kwargs to do_cli

* make accelerate launch default for non-preprocess commands

* fixing arg handling

* testing None placeholder approach

* removing hacky --use-gpu argument to preprocess command

* Adding brief README documentation for CLI

* remove (New)

* Initial CLI pytest tests

* progress on CLI pytest

* adding inference CLI tests; cleanup

* Refactor train CLI tests to remove various mocking

* Major CLI test refator; adding remaining CLI codepath test coverage

* pytest fixes

* remove integration markers

* parallelizing examples, deepspeed config downloads; rename test to match other CLI test naming

* moving cli pytest due to isolation issues; cleanup

* testing fixes; various minor improvements

* fix

* tests fix

* Update tests/cli/conftest.py

Co-authored-by: Wing Lian <[email protected]>

---------

Co-authored-by: Dan Saunders <[email protected]>
Co-authored-by: Wing Lian <[email protected]>
djsaunde added a commit that referenced this pull request Dec 17, 2024
* Initial CLI implementation with click package

* Adding fetch command for pulling examples and deepspeed configs

* Automating default options for CliArgs classes

* Mimicking existing no config behavior

* bugfix in choose_config

* Updating fetch to sync instead of re-download

* bugfix

* isort fix

* fixing yaml isort order

* pre-commit fixes

* simplifying argument parsing -- pass through kwargs to do_cli

* make accelerate launch default for non-preprocess commands

* fixing arg handling

* testing None placeholder approach

* removing hacky --use-gpu argument to preprocess command

* Adding brief README documentation for CLI

* remove (New)

* Initial CLI pytest tests

* progress on CLI pytest

* adding inference CLI tests; cleanup

* Refactor train CLI tests to remove various mocking

* Major CLI test refator; adding remaining CLI codepath test coverage

* pytest fixes

* remove integration markers

* parallelizing examples, deepspeed config downloads; rename test to match other CLI test naming

* moving cli pytest due to isolation issues; cleanup

* testing fixes; various minor improvements

* fix

* tests fix

* Update tests/cli/conftest.py

Co-authored-by: Wing Lian <[email protected]>

---------

Co-authored-by: Dan Saunders <[email protected]>
Co-authored-by: Wing Lian <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants